package com.ruoyi.project.jxy.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.FileUtil;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.framework.config.RuoYiConfig;
import com.ruoyi.project.jxy.domain.*;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.MultimediaInfo;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Callable;

/**
 * @ClassName UnZipThread
 * @Description TODO
 * @Author zheng
 * @Date 2020/8/13 16:08
 * @Version 1.0
 **/
public class FileInfoThread implements Callable {
    private static final Logger logger = LoggerFactory.getLogger(FileInfoThread.class);

    private int startIndex;
    private int endIndex;
    private File[] files;
    private String txtPath;
    private FileHistory fileHistory;

    public FileInfoThread(int startIndex, int endIndex, File[] files, String txtPath, FileHistory fileHistory) {
        this.startIndex = startIndex;
        this.endIndex = endIndex;
        this.files = files;
        this.txtPath = txtPath;
        this.fileHistory = fileHistory;
    }


    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    @Override
    public Object call() throws Exception {
        System.out.println("endIndex:" + endIndex);
        List lst = new ArrayList();
        //根路径
        String baseDir = RuoYiConfig.getProfile();
        logger.info("baseDir is :" + baseDir);
        //copy 源文件至新建文件目录(yyyy/mm/dd/wav)下
        String newWavPath = baseDir + "/" + fileHistory.getType() + "/" + DateUtils.datePath() + "/wav";
        String newTxtPath = baseDir + "/" + fileHistory.getType() + "/" + DateUtils.datePath() + "/txt";
        String imgPath = baseDir + "/" + fileHistory.getType() + "/" + DateUtils.datePath() + "/img";
        //文件夹是否存在,不存在创建
        if (!FileUtil.newFile(newWavPath).exists()) {
            FileUtil.newFile(newWavPath).mkdirs();
        }
        if (!FileUtil.newFile(imgPath).exists()) {
            FileUtil.newFile(imgPath).mkdirs();
        }
        if (!FileUtil.newFile(newTxtPath).exists()) {
            FileUtil.newFile(newTxtPath).mkdirs();
        }
        for (int i = startIndex; i < endIndex; i++) {
            File wavFile = files[i];
            HashMap beanMap = new HashMap();
            beanMap.put("region", fileHistory.getRegion());
            beanMap.put("theme", fileHistory.getTheme());
            beanMap.put("name", fileHistory.getName());
            beanMap.put("sex", fileHistory.getSex());
            beanMap.put("age", fileHistory.getAge());
            beanMap.put("createTime", new Date());
            //语音识别
            if ("0".equals(fileHistory.getType())) {

                //md5
                String md5 = DigestUtils.md5Hex(FileUtil.readBytes(wavFile));
                //文件md5
                beanMap.put("fileMd5", md5);
                //音频文件后缀名
                String extension = FilenameUtils.getExtension(wavFile.getName());
                String newWavFilePath = newWavPath + "/" + md5 + "." + extension;
                //copy 文件
                FileUtil.copy(wavFile.getAbsolutePath(), newWavFilePath, true);
                //文件存储路径
                beanMap.put("path", "/profile/" + fileHistory.getType() + "/" + DateUtils.datePath() + "/wav" + "/" + md5 + "." + extension);
                //文件名称
                beanMap.put("displayName", md5 + "." + extension);
                //内容
                String txtFilePath = txtPath + "/" + wavFile.getName().substring(0, wavFile.getName().indexOf(".")) + ".txt";
                String txtContent = FileUtil.readString(FileUtil.newFile(txtFilePath), Charset.defaultCharset());
                //copy txt 文件
                FileUtil.copy(txtFilePath, newTxtPath + "/" + md5 + ".txt", true);
                beanMap.put("content", txtContent);
                //音频时长
                Long duration = getDuration(wavFile);
                beanMap.put("duration", duration);
                //音频时长(text)
                beanMap.put("durationText", getDuration(duration));
                //文件大小
                beanMap.put("fileSize", wavFile.length());
                //创建人
                //asrRecord.setCreateUser(SecurityUtils.getUsername());
                AsrRecord asrRecord = BeanUtil.mapToBean(beanMap, AsrRecord.class, true);
                lst.add(asrRecord);
            }
            //合成
            else if ("1".equals(fileHistory.getType())) {

                //md5
                String md5 = DigestUtils.md5Hex(FileUtil.readBytes(wavFile));
                //文件md5
                beanMap.put("fileMd5", md5);
                //音频文件后缀名
                String extension = FilenameUtils.getExtension(wavFile.getName());
                String newWavFilePath = newWavPath + "/" + md5 + "." + extension;
                //copy 文件
                FileUtil.copy(wavFile.getAbsolutePath(), newWavFilePath, true);
                //文件存储路径
                beanMap.put("path", "/profile/" + fileHistory.getType() + "/" + DateUtils.datePath() + "/wav" + "/" + md5 + "." + extension);
                //文件名称
                beanMap.put("displayName", md5 + "." + extension);
                //内容
                String txtFilePath = txtPath + "/" + wavFile.getName().substring(0, wavFile.getName().indexOf(".")) + ".txt";
                String txtContent = FileUtil.readString(FileUtil.newFile(txtFilePath), Charset.defaultCharset());
                //copy txt 文件
                FileUtil.copy(txtFilePath, newTxtPath + "/" + md5 + ".txt", true);
                beanMap.put("content", txtContent);
                //音频时长
                Long duration = getDuration(wavFile);
                beanMap.put("duration", duration);
                //音频时长(text)
                beanMap.put("durationText", getDuration(duration));
                //文件大小
                beanMap.put("fileSize", wavFile.length());
                //创建人
                //asrRecord.setCreateUser(SecurityUtils.getUsername());
                TtsRecord ttsRecord = BeanUtil.mapToBean(beanMap, TtsRecord.class, true);
                lst.add(ttsRecord);
            }
            //发音词典
            else if ("2".equals(fileHistory.getType())) {
                //蒙文
                String otherContent = FileUtil.readString(wavFile, Charset.defaultCharset());
                beanMap.put("otherContent", otherContent);
                //中文
                String txtContent = FileUtil.readString(txtPath + File.separator + wavFile.getName(), Charset.defaultCharset());
                beanMap.put("content", txtContent);
                TalkingDictRecord talkingDictRecord = BeanUtil.mapToBean(beanMap, TalkingDictRecord.class, true);
                lst.add(talkingDictRecord);
            }
            //对齐语料
            else if ("3".equals(fileHistory.getType())) {
                String otherContent = FileUtil.readString(wavFile, Charset.defaultCharset());
                beanMap.put("otherContent", otherContent);
                //中文
                String txtContent = FileUtil.readString(txtPath + File.separator + wavFile.getName(), Charset.defaultCharset());
                beanMap.put("content", txtContent);
                AlignedCorpusRecord alignedCorpusRecord = BeanUtil.mapToBean(beanMap, AlignedCorpusRecord.class, true);
                lst.add(alignedCorpusRecord);
            }
            //图片识别
            else if ("4".equals(fileHistory.getType())) {
                //md5
                String md5 = DigestUtils.md5Hex(FileUtil.readBytes(wavFile));
                //文件md5
                beanMap.put("fileMd5", md5);
                //音频文件后缀名
                String extension = FilenameUtils.getExtension(wavFile.getName());
                String newWavFilePath = imgPath + "/" + md5 + "." + extension;
                //copy 文件
                FileUtil.copy(wavFile.getAbsolutePath(), newWavFilePath, true);
                //文件存储路径
                beanMap.put("path", "/profile/" + fileHistory.getType() + "/" + DateUtils.datePath() + "/img" + "/" + md5 + "." + extension);
                //文件名称
                beanMap.put("displayName", md5 + "." + extension);
                //内容
                String txtFilePath = txtPath + "/" + wavFile.getName().substring(0, wavFile.getName().indexOf(".")) + ".txt";
                String txtContent = FileUtil.readString(FileUtil.newFile(txtFilePath), Charset.defaultCharset());
                //copy txt 文件
                FileUtil.copy(txtFilePath, newTxtPath + "/" + md5 + ".txt", true);
                beanMap.put("content", txtContent);
                //Imgi
                BufferedImage bufferedImage = ImageIO.read(wavFile);
                String resolution = bufferedImage.getWidth() + "x" + bufferedImage.getHeight();
                beanMap.put("resolution", resolution);
                //文件大小
                beanMap.put("fileSize", wavFile.length());
                //创建人
                //asrRecord.setCreateUser(SecurityUtils.getUsername());
                ImgRecord imgRecord = BeanUtil.mapToBean(beanMap, ImgRecord.class, true);
                lst.add(imgRecord);
            }
            //词典
            else if ("5".equals(fileHistory.getType())) {
                //md5
                String md5 = DigestUtils.md5Hex(FileUtil.readBytes(wavFile));
                //文件md5
                beanMap.put("fileMd5", md5);
                //音频文件后缀名
                String extension = FilenameUtils.getExtension(wavFile.getName());
                String newWavFilePath = newWavPath + "/" + md5 + "." + extension;
                //copy 文件
                FileUtil.copy(wavFile.getAbsolutePath(), newWavFilePath, true);
                //文件存储路径
                beanMap.put("path", "/profile/" + fileHistory.getType() + "/" + DateUtils.datePath() + "/wav" + "/" + md5 + "." + extension);
                //文件名称
                beanMap.put("displayName", md5 + "." + extension);
                //内容
                String txtFilePath = txtPath + "/" + wavFile.getName().substring(0, wavFile.getName().indexOf(".")) + ".txt";
                String txtContent = FileUtil.readString(FileUtil.newFile(txtFilePath), Charset.defaultCharset());
                //copy txt 文件
                FileUtil.copy(txtFilePath, newTxtPath + "/" + md5 + ".txt", true);
                beanMap.put("content", txtContent);
                //音频时长
                Long duration = getDuration(wavFile);
                beanMap.put("duration", duration);
                //音频时长(text)
                beanMap.put("durationText", getDuration(duration));
                //文件大小
                beanMap.put("fileSize", wavFile.length());
                //创建人
                //asrRecord.setCreateUser(SecurityUtils.getUsername());
                DictionaryRecord dictionaryRecord = BeanUtil.mapToBean(beanMap, DictionaryRecord.class, true);
                lst.add(dictionaryRecord);
            }
        }
        return lst;
    }

    /**
     * 音频文件获取文件时长
     *
     * @param source
     * @return
     */
    public static Long getDuration(File source) {

        Encoder encoder = new Encoder();
        long ls = 0;
        MultimediaInfo m;
        try {
            m = encoder.getInfo(source);
            ls = m.getDuration() / 1000;

        } catch (Exception e) {
            System.out.println("获取音频时长有误：" + e.getMessage());
        }
        return ls;
    }

    public static String getDuration(Long duration) {
        int mi = 60;
        int hh = mi * 60;
        long hour = duration / hh;
        long minute = (duration - hour * hh) / mi;
        long second = (duration - hour * hh - minute * mi);
        //小时
        String strHour = hour < 10 ? "0" + hour : "" + hour;
        //分钟
        String strMinute = minute < 10 ? "0" + minute : "" + minute;
        //秒
        String strSecond = second < 10 ? "0" + second : "" + second;
        return strHour + ":" + strMinute + ":" + strSecond;
    }
}
